home *** CD-ROM | disk | FTP | other *** search
/ Best of Shareware / Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso / mac / DOS / UTILITY / LZESHE12 / UNLZEXE.C < prev    next >
Text File  |  1990-03-29  |  7KB  |  264 lines

  1. /* unlzexe.c
  2. * unlzexe ver 0.2 (PC-VAN UTJ44266 Kou )
  3. *   UNLZEXE converts the compressed file by lzexe(ver.0.90,0.91) to the
  4. *   UNcompressed executable one.
  5. */
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <string.h>
  9. #define FAILURE    1
  10. #define SUCCESS 0
  11.  
  12. typedef unsigned int WORD;
  13. typedef unsigned char BYTE;
  14.  
  15.  
  16. main(int argc,char **argv){
  17.     int rdhead(FILE *,int *);
  18.     void mkreltbl(FILE *,FILE *,int);
  19.     void unpack(FILE *,FILE *);
  20.     void wrhead(FILE *);
  21.  
  22.     FILE *ifile,*ofile;
  23.     int ver;
  24.     
  25.     printf("UNLZEXE Ver. 0.2\n");
  26.         if(argc!=3){
  27.         printf("usage:UNLZEXE packedfile unpackedfile");
  28.         exit(1);
  29.     }
  30.     if((ifile=fopen(argv[1],"rb"))==NULL){
  31.         printf("'%s' :not found.",argv[1]);
  32.         exit(1);
  33.     }
  34.      
  35.     if(rdhead(ifile,&ver)!=SUCCESS){
  36.         printf("'%s' is not LZEXE file.",argv[1]);
  37.     }else {
  38.         if((ofile=fopen(argv[2],"w+b"))==NULL){
  39.         printf("'%s' :can't open.",argv[2]);
  40.         fclose(ifile);
  41.         exit(1);
  42.         }
  43.         printf("file '%s' is compressed by LZEXE Ver. ",argv[1]);
  44.         switch(ver){
  45.         case 90: printf("0.90\n"); break;
  46.         case 91: printf("0.91\n"); break;
  47.     }
  48.         mkreltbl(ifile,ofile,ver);
  49.         unpack(ifile,ofile);
  50.         wrhead(ofile);
  51.         fclose(ofile);
  52.         printf("unpacked file '%s' is generated.\n",argv[2]);
  53.     }
  54.     fclose(ifile);
  55. }
  56.  
  57. /*-------------------------------------------*/
  58. static WORD ihead[0x10],ohead[0x10],inf[8];
  59. static WORD allocsize;
  60. static long fpos,loadsize;
  61.  
  62. /* EXE header test (is it LZEXE file?) */
  63. int rdhead(FILE *ifile ,int *ver){
  64.     if(fread(ihead,sizeof ihead[0],0x10,ifile)!=0x10)
  65.         return FAILURE;
  66.     memcpy(ohead,ihead,sizeof ihead[0] * 0x10);
  67.     if(ihead[0]!=0x5a4d || ihead[4]!=2 || ihead[0x0d]!=0)
  68.         return FAILURE;
  69.     if(ihead[0x0c]==0x1c && memcmp(&ihead[0x0e],"LZ09",4)==0){
  70.         *ver=90; return SUCCESS ;
  71.     }
  72.     if(ihead[0x0c]==0x1c && memcmp(&ihead[0x0e],"LZ91",4)==0){
  73.         *ver=91; return SUCCESS ;
  74.     }
  75.     return FAILURE;
  76. }
  77.  
  78. /* make relocation table */
  79. void mkreltbl(FILE *ifile,FILE *ofile,int ver) {
  80.     void reloc90();
  81.     void reloc91();
  82.     int i;
  83.     
  84.     allocsize=((ihead[1]+16-1)>>4) + ((ihead[2]-1)<<5) - ihead[4] + ihead[5];
  85.     fpos=(long)(ihead[0x0b]+ihead[4])<<4;        /* goto CS:0000 */
  86.     fseek(ifile,fpos,SEEK_SET);
  87.     fread(inf, sizeof inf[0], 0x08, ifile);
  88.     ohead[0x0a]=inf[0];        /* IP */
  89.     ohead[0x0b]=inf[1];        /* CS */
  90.     ohead[0x08]=inf[2];        /* SP */
  91.     ohead[0x07]=inf[3];        /* SS */
  92.     /* inf[4]:size of compressed load module (PARAGRAPH)*/
  93.     /* inf[5]:increase of load module size (PARAGRAPH)*/
  94.     /* inf[6]:size of decompressor with  compressed relocation table (BYTE) */
  95.     /* inf[7]:check sum of decompresser with compressd relocation table(Ver.0.90) */
  96.     ohead[0x0c]=0x1c;        /* start position of relocation table */
  97.     fseek(ofile,0x1cL,SEEK_SET);
  98.     switch(ver){
  99.     case 90: reloc90(ifile,ofile,fpos);
  100.              break;
  101.     case 91: reloc91(ifile,ofile,fpos);
  102.              break;
  103.     }
  104.     i=ohead[3]*4+ohead[0x0c];
  105.     ohead[4]=((i+0x1ff) & ~0x1ff)>>4;
  106.     
  107.     for(i=0x200-(i & 0x1ff); i>0; i--)
  108.        putc(0, ofile);
  109. }
  110. /* for LZEXE ver 0.90 */
  111. void reloc90(FILE *ifile,FILE *ofile,long fpos) {
  112.     unsigned int c;
  113.     WORD rel_count=0;
  114.     WORD rel_item[2];        /* [0]:offset, [1]:segment */
  115.  
  116.     fseek(ifile,fpos+0x19d,SEEK_SET); 
  117.                     /* 0x19d=compressed relocation table address */
  118.     for(rel_item[1]=0;rel_item[1]<0x10;rel_item[1]++) {
  119.         if((c=getw(ifile))==0)
  120.             continue;
  121.         else {
  122.             for(;c>0;c--) {
  123.                 rel_item[0]=getw(ifile);
  124.                 putw(rel_item[0],ofile);
  125.                 putw(rel_item[1],ofile);
  126.                 rel_count++;
  127.             }
  128.         }
  129.     }
  130.     ohead[3]=rel_count;
  131. }
  132. /* for LZEXE ver 0.91*/
  133. void reloc91(FILE *ifile,FILE *ofile,long fpos) {
  134.     WORD span;
  135.     WORD rel_count=0;
  136.     WORD rel_item[2];        /* [0]:offset, [1]:segment */
  137.  
  138.     fseek(ifile,fpos+0x158,SEEK_SET);
  139.                     /* 0x158=compressed relocation table address */
  140.     rel_item[0]=0; rel_item[1]=0;
  141.     for(;;) {
  142.         if((span=getc(ifile))==0) {
  143.             span=getw(ifile);
  144.             if(span==0){
  145.                 rel_item[1] += 0x0fff;
  146.                 continue;
  147.             } else if(span==1){
  148.                 break;
  149.             }
  150.         }
  151.         rel_item[0] += span;
  152.         rel_item[1] += (rel_item[0] & ~0x0f)>>4;
  153.         rel_item[0] &= 0x0f;
  154.         putw(rel_item[0],ofile);
  155.         putw(rel_item[1],ofile);
  156.         rel_count++;
  157.     }
  158.     ohead[3]=rel_count;
  159. }
  160.  
  161. /*---------------------*/
  162. typedef struct {
  163.         FILE  *fp;
  164.         WORD  buf;
  165.         BYTE  count;
  166.     } bitstream;
  167.  
  168. void initbits(bitstream *,FILE *);
  169. int getbit(bitstream *);
  170.  
  171. /*---------------------*/
  172. /* decompressor routine */
  173. void unpack(FILE *ifile,FILE *ofile){
  174.     int len;
  175.     int span;
  176.     long fpos;
  177.     bitstream bits;
  178.     static BYTE data[0x4500], *p=data;
  179.     
  180.     fpos=(long)(ihead[0x0b]-inf[4]+ihead[4])<<4;
  181.     fseek(ifile,fpos,SEEK_SET);
  182.     fpos=(long)ohead[4]<<4;
  183.     fseek(ofile,fpos,SEEK_SET);
  184.     initbits(&bits,ifile);
  185.     printf(" unpacking. ");
  186.     for(;;){
  187.         if(p-data>0x4000){
  188.             fwrite(data,sizeof data[0],0x2000,ofile);
  189.             p-=0x2000;
  190.             memcpy(data,data+0x2000,p-data);
  191.             putchar('.');
  192.         }
  193.         if(getbit(&bits)) {
  194.             *p++=getc(ifile);
  195.             continue;
  196.         }
  197.         if(!getbit(&bits)) {
  198.             len=getbit(&bits)<<1;
  199.             len |= getbit(&bits);
  200.             len += 2;
  201.             span=getc(ifile) | 0xff00;
  202.         } else {
  203.             span=(BYTE)getc(ifile);
  204.             len=getc(ifile);
  205.             span |= ((len & ~0x07)<<5) | 0xe000;
  206.             len = (len & 0x07)+2; 
  207.             if (len==2) {
  208.                 len=getc(ifile);
  209.  
  210.                 if(len==0)
  211.                     break;
  212.  
  213.                 if(len==1)
  214.                     continue; /* segment change */
  215.                 else
  216.                     len++;
  217.             }
  218.         }
  219.         for( ;len>0;len--,p++){
  220.             *p=*(p+span);
  221.         }
  222.     }
  223.     if(p!=data)
  224.         fwrite(data,sizeof data[0],p-data,ofile);
  225.     loadsize=ftell(ofile)-fpos;
  226.     printf("end\n");
  227. }
  228.  
  229. /* write EXE header*/
  230. void wrhead(FILE *ofile) {
  231.     if(ihead[6]!=0) {
  232.         ohead[5]=allocsize-((loadsize+15)>>4);
  233.         if(ihead[6]!=0xffff)
  234.             ohead[6]-=(ihead[5]-ohead[5]);
  235.     }
  236.     ohead[1]=(loadsize+(ohead[4]<<4))&0x1ff;
  237.     ohead[2]=(loadsize+(ohead[4]<<4)+0x1ff) >>9;
  238.     fseek(ofile,0L,SEEK_SET);
  239.     fwrite(ohead,sizeof ohead[0],0x0e,ofile);
  240. }
  241. /*-------------------------------------------*/
  242.  
  243. /* get compress information bit by bit */
  244. void initbits(bitstream *p,FILE *filep){
  245.     p->fp=filep;
  246.     p->count=0x10;
  247.     p->buf=getw(filep);
  248.     /* printf("%04x ",p->buf); */
  249. }
  250.  
  251. int getbit(bitstream *p) {
  252.     int b;
  253.     b = p->buf & 1;
  254.     if(--p->count == 0){
  255.         (p->buf)=getw(p->fp);
  256.         /* printf("%04x ",p->buf); */
  257.         p->count= 0x10;
  258.     }else
  259.         p->buf >>= 1;
  260.     
  261.     return b;
  262. }
  263.  
  264.